#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * HibernateSQLQueryUtil.java
 * Modification History
 * *************************************************************
 * Date         Author                          Comment
 * Jan 08, 2014 Venkaiah Chowdary Koneru        Created
 * *************************************************************
 */
package ${package}.support.hibernate;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

import ${package}.dto.ListProp;
import ${package}.support.CommonsUtil;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.util.StringUtils;

/**
 * Utility class to hold SQL Query related functionality.
 * 
 * @author Venkaiah Chowdary Koneru
 */
public final class HibernateSQLQueryUtil extends AbstractHibernateQueryUtil
{
    /**
     * Helper method to ease the query process for named queries
     * 
     * @param sessionFactory
     *            must not be null.
     * @param queryWithSelect
     *            must not be blank. plain SQL query with select clause. e.g.
     *            <code>select usr.id, usr.name, ... from ${parentArtifactId}_user usr</code>
     * @param countQueryWithSelect
     *            must not be blank. plain SQL query with select clause. e.g.
     *            <code>select count(*) from ...</code>.
     * @param listProp
     *            can be null.
     * @param resultClass
     *            can be null.
     * @param parameters
     *            can be null if no parameter is required.
     * @return List of the result object.
     */
    public static List<?> list(SessionFactory sessionFactory,
            final String queryWithSelect, final String countQueryWithSelect,
            final ListProp listProp, final Class<?> resultClass,
            final Map<String, Object> parameters)
    {
        if (sessionFactory == null || !StringUtils.hasText(queryWithSelect))
        {
            return null;
        }

        Session session = sessionFactory.getCurrentSession();

        if (StringUtils.hasText(countQueryWithSelect))
        {
            setCountData(session.createSQLQuery(countQueryWithSelect),
                    listProp, parameters);
        }

        SQLQuery sqlQuery = session.createSQLQuery(queryWithSelect
                + generateSorting(listProp, null));

        sqlQuery.setResultTransformer(Transformers.aliasToBean(resultClass));

        setParameters(parameters, sqlQuery);

        setPagination(listProp, sqlQuery);

        return sqlQuery.list();
    }

    /**
     * Executes the Count query and sets the total records property value of
     * list prop.
     * 
     * @param countQuery
     *            count query. this should not be empty.
     * @param listProp
     *            list prop object
     * @param parameters
     *            parameters
     */
    private static void setCountData(Query countQuery, ListProp listProp,
            Map<String, Object> parameters)
    {
        if (countQuery != null && listProp != null
                && listProp.getStartIndex() >= getStartIndex())
        {
            setParameters(parameters, countQuery);

            List<?> countList = countQuery.list();
            if (CommonsUtil.isEmpty(countList))
            {
                listProp.setTotalRecords(0);
            }
            else
            {
                listProp.setTotalRecords(((BigInteger) countList.iterator()
                        .next()).longValue());
            }
        }
    }

    /**
     * Constructor. private to prevent unnecessary instantiation.
     */
    private HibernateSQLQueryUtil()
    {
    }
}
